AWS CDK でスタック合成時に 'Only root constructs may have an empty ID' というエラーが発生する場合の確認ポイント

AWS CDK でスタック合成時に 'Only root constructs may have an empty ID' というエラーが発生する場合の確認ポイント

Clock Icon2025.01.21

こんにちは、製造ビジネステクノロジー部の若槻です。

今回は AWS CDK でスタックの合成時に Only root constructs may have an empty ID というエラーが発生する場合の確認ポイントについてです。

事象

次のように SNS トピックに EmailSubscription を追加する CDK スタックを作成しました。

lib/main-stack.ts
import * as cdk from 'aws-cdk-lib';
import { Construct } from 'constructs';
import * as sns from 'aws-cdk-lib/aws-sns';
import * as subscriptions from 'aws-cdk-lib/aws-sns-subscriptions';

export class MainStack extends cdk.Stack {
  constructor(scope: Construct, id: string, props: cdk.StackProps) {
    super(scope, id, props);

    const SUBSCRIPTION_EMAIL_ADDRESS = process.env.SUBSCRIPTION_EMAIL_ADDRESS || '';

    const topic = new sns.Topic(this, 'Topic');

    topic.addSubscription(
      new subscriptions.EmailSubscription(SUBSCRIPTION_EMAIL_ADDRESS)
    );
  }
}

上記の CDK スタックを合成(Synth)すると Only root constructs may have an empty ID というエラーが発生します。

$ npx cdk synth
/Users/wakatsuki.ryuta/projects/cm-rwakatsuki/cdk_sample_app/node_modules/constructs/src/construct.ts:67
      throw new Error('Only root constructs may have an empty ID');
            ^
Error: Only root constructs may have an empty ID
    at new Node (/Users/wakatsuki.ryuta/projects/cm-rwakatsuki/cdk_sample_app/node_modules/constructs/src/construct.ts:67:13)
    at new Construct (/Users/wakatsuki.ryuta/projects/cm-rwakatsuki/cdk_sample_app/node_modules/constructs/src/construct.ts:482:17)
    at new Resource (/Users/wakatsuki.ryuta/projects/cm-rwakatsuki/cdk_sample_app/node_modules/aws-cdk-lib/core/lib/resource.js:1:1309)
    at new Subscription (/Users/wakatsuki.ryuta/projects/cm-rwakatsuki/cdk_sample_app/node_modules/aws-cdk-lib/aws-sns/lib/subscription.js:1:707)
    at Topic.addSubscription (/Users/wakatsuki.ryuta/projects/cm-rwakatsuki/cdk_sample_app/node_modules/aws-cdk-lib/aws-sns/lib/topic-base.js:1:1594)
    at new MainStack (/Users/wakatsuki.ryuta/projects/cm-rwakatsuki/cdk_sample_app/lib/main-stack.ts:14:11)
    at Object.<anonymous> (/Users/wakatsuki.ryuta/projects/cm-rwakatsuki/cdk_sample_app/bin/cdk_sample_app.ts:13:1)
    at Module._compile (node:internal/modules/cjs/loader:1241:14)
    at Module.m._compile (/Users/wakatsuki.ryuta/.npm/_npx/1bf7c3c15bf47d04/node_modules/ts-node/src/index.ts:1618:23)
    at Module._extensions..js (node:internal/modules/cjs/loader:1295:10)
Subprocess exited with error 1

原因、解決

もうお分かりかと思いますが、エラーの原因は subscriptions.EmailSubscription の引数に空文字列が渡されていたためでした。シェル上の環境変数 SUBSCRIPTION_EMAIL_ADDRESS を確認すると未設定となっています。

$ echo $SUBSCRIPTION_EMAIL_ADDRESS

環境変数を設定した上で CDK スタックを合成するとエラーが解消されます。

$ export SUBSCRIPTION_EMAIL_ADDRESS=hoge@example.com
$ npx cdk synth
Resources:
  TopicBFC7AF6E:
    Type: AWS::SNS::Topic
    Metadata:
      aws:cdk:path: Main/Topic/Resource
  TopichogeexamplecomE5093F3B:
    Type: AWS::SNS::Subscription
    Properties:
      Endpoint: hoge@example.com
      Protocol: email
      TopicArn:
        Ref: TopicBFC7AF6E
    Metadata:
      aws:cdk:path: Main/Topic/hoge@example.com/Resource
  CDKMetadata:
    Type: AWS::CDK::Metadata
    Properties:
      Analytics: v2:deflate64:H4sIAAAAAAAA/02JSw6DMAwFz8KemI9UVay5AXSPwAmSgdooTtoF6t3bKJuu3ryZFpr7DZpifqtBu5uDFrjGMONe/tSkrHA95CQs+5UzjHFR9HQGEk72/3+SGJxK9OgS98KWcmGxDjatXm0NHdTFpkTGRw70dDDk/QL+boxwjwAAAA==
    Metadata:
      aws:cdk:path: Main/CDKMetadata/Default
    Condition: CDKMetadataAvailable

ちなみに export SUBSCRIPTION_EMAIL_ADDRESS=hoge のようにメールアドレスの形式でない値を設定した場合でもエラーは発生し無いので注意しましょう。

おわりに

AWS CDK でスタック合成時に 'Only root constructs may have an empty ID' というエラーが発生する場合の確認ポイントについて解説しました。

今回の最低限のサンプルコードだったので原因の特定は容易でしたが、エラーメッセージは分かりにくいため、実際のプロジェクトで発生した場合は原因特定に時間がかかるかもしれません。そのような時に本記事が参考になれば幸いです。

以上

Share this article

facebook logohatena logotwitter logo

© Classmethod, Inc. All rights reserved.